<?php
/**
 * 用户
 * @date    2020-01-01
 * @author  kiro
 * @email   294843009@qq.com
 * @version 1.0
 */
namespace App\Http\Controllers\Api\V1;

use App\Models\Article;
use App\Models\Config;
use App\Models\Download;
use App\Models\Follow;
use App\Models\Give;
use App\Models\Like;
use App\Models\Movie;
use App\Models\MovieHistory;
use App\Models\Rebate;
use App\Models\SearchLog;
use App\Models\Share;
use App\Models\SignInLog;
use App\Models\SpeakRelate;
use App\Models\User;
use App\Models\UserAccountLog;
use App\Models\UserBlacklist;
use App\Models\UserBook;
use App\Models\UserFreeLog;
use App\Models\UserGroup;
use App\Models\UserGroupRelate;
use App\Models\UserGroupTags;
use App\Models\UserGroupTagsRelate;
use App\Models\UserHasTags;
use App\Models\UserInformLog;
use App\Models\UserRelate;
use App\Models\UserTags;
use App\Models\UserVipLog;
use App\Models\UserVipShop;
use App\Models\UserWithdrawLog;
use App\Models\Video;
use App\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use TencentCloud\Common\Sign;
use function GuzzleHttp\Psr7\str;

class UserController extends ApiController
{
    // 根据用户username或者user_id获取用户信息
    public function get(Request $request)
    {
        $username = $request->get('username', '');
        $user_id = (int)$request->get('user_id', '');
        if (empty($user_id) && empty($username)) {
            return $this->error('user_id和username不能都为空');
        }
        if ($user_id) {
            $user = User::where('id', $user_id)
                ->whereIn('status', [1, 2])
                ->select('id', 'username', 'nickname', 'avatar', 'vip_end_time', 'position', 'desc')
                ->first();
        } elseif ($username) {
            $user = User::where('username', $username)
                ->whereIn('status', [1, 2])
                ->select('id', 'username', 'nickname', 'avatar', 'vip_end_time', 'position', 'desc')
                ->first();
        }
        $user->avatar = dealAvatar($user->avatar);
        $user->is_vip = isVip($user->vip_end_time);
        $user->vip_end_time = dealVipEndTime($user->vip_end_time);
        // 粉丝数
        $user->follow_num = dealNum(Follow::getFollowNum($user->id));
        // 关注数
        $user->my_follow_num = dealNum(Follow::getMyFollowNum($user->id));
        // 获赞数
        $user->like_num = dealNum(Like::getNum($user->id));
        // 推广数
        $user->ref_num = dealNum(User::getRefNum($user->id));
        // 标签数
        $user->tags_num = UserHasTags::where('user_id', $user->id)->count();
        $is_follow = 0;
        $same_tags = 0;
        $tags = [];
        if ($this->getUserId()) {
            $follow = Follow::where('user_id',$this->getUserId())->where('follow_id', $user->id)->where('status', 1)->count();
            $is_follow = $follow ? 1:0;
            $tag_ids = UserHasTags::where('user_id', $this->getUserId())->pluck('tag_id')->toArray();
            $same_tags = UserHasTags::where('user_id', $user->id)->whereIn('tag_id', $tag_ids)->count();
            $tags = UserHasTags::where('user_id', $user->id)->get();
            foreach ($tags as &$tag) {
                $tag['tag_name'] = UserTags::where('id', $tag['tag_id'])->value('name');
                $is_same = 0;
                if (in_array($tag['tag_id'], $tag_ids)) {
                    $is_same = 1;
                }
                $tag['is_same'] = $is_same;
            }
        }
        $user->is_follow = $is_follow;
        $user->same_tags = $same_tags;
        $user->tags = $tags;
        return $this->success('成功', $user);
    }

    // 搜索用户记录
    public function search(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = User::where('status', 1)
            ->where(function($query) use ($request){
                if ($request->keyword) {
                    $query->where('username', $request->keyword);
                    if ($request->is_all) {
                        $query->orWhere('nickname', 'like', '%' . $request->keyword . '%');
                    }
                }
            })
            ->count();
        $data = User::where('status', 1)
            ->where(function($query) use ($request){
                if ($request->keyword) {
                    $query->where('username', $request->keyword);
                    if ($request->is_all) {
                        $query->orWhere('nickname', 'like', '%' . $request->keyword . '%');
                    }
                }
            })
            ->select('id', 'username', 'nickname', 'avatar', 'vip_end_time', 'company_id', 'department_id')
            ->orderBy('id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->get()
            ->toArray();
        // 已经登录情况
        if ($this->getUserId()) {
            // 是否关注
            $user_ids = array_unique(array_column($data, 'id'));
            $follows = Follow::where('user_id',$this->getUserId())->whereIn('follow_id', $user_ids)->where('status', 1)->pluck('follow_id')->toArray();
            $tag_ids = UserHasTags::where('user_id', $this->getUserId())->pluck('tag_id')->toArray();
        }
        foreach ($data as &$value) {
            $value['avatar'] = dealAvatar($value['avatar']);
            $value['is_vip'] = isVip($value['vip_end_time']);
            $value['vip_end_time'] = dealVipEndTime($value['vip_end_time']);
            $is_follow = 0;
            $same_tags = 0;
            if ($this->getUserId()) {
                if (in_array($value['id'], $follows)) {
                    $is_follow = 1;
                }
                if ($tag_ids) {
                    $same_tags = UserHasTags::where('user_id', $value['id'])->whereIn('tag_id', $tag_ids)->count();
                }
            }
            $value['is_follow'] =  $is_follow;
            $value['same_tags'] = $same_tags;
            // 作品数
            $video_num = Video::getNum($value['id']);
            $article_num = Article::getNum($value['id']);
            $product_num = $video_num + $article_num;
            $value['product_num'] = dealNum($product_num);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 推广记录
    public function refer(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = User::where('status', 1)
        ->where('pid', $this->getUserId())
        ->count();
        $data = User::where('status', 1)
        ->where('pid', $this->getUserId())
        ->select('id', 'username', 'nickname', 'avatar')
        ->orderBy('id', 'DESC')
        ->offset($offset)
        ->limit($limit)
        ->get();
        foreach ($data as &$value) {
            $value['avatar'] = dealAvatar($value['avatar']);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 账变记录
    public function accountLog(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserAccountLog::leftJoin('users', 'users.id', '=', 'user_account_log.user_id')
        ->where('user_account_log.user_id', $this->getUserId())
        ->count();
        $data = UserAccountLog::leftJoin('users', 'users.id', '=', 'user_account_log.user_id')
        ->where('user_account_log.user_id', $this->getUserId())
        ->select('user_account_log.*')
        ->orderBy('user_account_log.id', 'DESC')
        ->offset($offset)
        ->limit($limit)
        ->get()
        ->toArray();
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 提现记录
    public function withdraw(Request $request)
    {
        $type = $request->get('type', '');
        $amount = $request->get('amount', 0);
        $remark = $request->get('remark', '提现');

        if (empty($type)) {
            return $this->error('类型不能为空');
        }

        if ($amount <= 0) {
            return $this->error('提现金额必须大于0');
        }

        $data = [];
        $data['user_id'] = $this->getUserId();
        $data['type'] = $type;
        $data['status'] = 1;

        switch ($type) {
            case UserAccountLog::TYPE_AMOUNT:
                $data['amount'] = $amount;
                break;
            case UserAccountLog::TYPE_INTEGRAL:
                $data['integral'] = $amount;
                break;
            case UserAccountLog::TYPE_GOLD:
                $data['gold'] = $amount;
                break;
            default: return $this->error('类型不正确');
        }

        try {
            UserService::doAccount($this->getUserId(), -$amount, $remark, $type, UserAccountLog::SOURCE_WITHDRAW);
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }

        $data['remark'] = $remark;

        $res = UserWithdrawLog::create($data);
        if ($res === false) {
            return $this->error('提现失败');
        }
        return $this->success('提现成功');
    }


    // 提现记录
    public function withdrawLog(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserWithdrawLog::leftJoin('users', 'users.id', '=', 'user_withdraw_log.user_id')
        ->where('user_withdraw_log.user_id', $this->getUserId())
        ->count();
        $data = UserWithdrawLog::leftJoin('users', 'users.id', '=', 'user_withdraw_log.user_id')
        ->where('user_withdraw_log.user_id', $this->getUserId())
        ->select('user_withdraw_log.*')
        ->orderBy('user_withdraw_log.id', 'DESC')
        ->offset($offset)
        ->limit($limit)
        ->get()
        ->toArray();
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 举报记录
    public function inform(Request $request)
    {
        $type = $request->get('type', 0);
        $to_user_id = $request->get('to_user_id', 0);
        $content = $request->get('content', '');

        if (empty($content)) {
            return $this->error('举报内容不能为空');
        }

        $data = [];
        $data['user_id'] = $this->getUserId();
        $data['to_user_id'] = $to_user_id;
        $data['content'] = $content;
        $data['type'] = $type;
        $data['status'] = 1;

        $res = UserInformLog::create($data);
        if ($res === false) {
            return $this->error('提交失败');
        }
        return $this->success('提交成功');
    }


    // 举报记录
    public function informLog(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserInformLog::leftJoin('users', 'users.id', '=', 'user_inform_log.user_id')
            ->where('user_inform_log.user_id', $this->getUserId())
            ->count();
        $data = UserInformLog::leftJoin('users', 'users.id', '=', 'user_inform_log.user_id')
            ->where('user_inform_log.user_id', $this->getUserId())
            ->select('user_inform_log.*')
            ->orderBy('user_inform_log.id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->get()
            ->toArray();
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // VIP充值记录
    public function vipLog(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserVipLog::leftJoin('users', 'users.id', '=', 'user_vip_log.user_id')
        ->where('user_vip_log.user_id', $this->getUserId())
        ->count();
        $data = UserVipLog::leftJoin('users', 'users.id', '=', 'user_vip_log.user_id')
        ->where('user_vip_log.user_id', $this->getUserId())
        ->select('user_vip_log.*')
        ->orderBy('user_vip_log.id', 'DESC')
        ->offset($offset)
        ->limit($limit)
        ->get()
        ->toArray();
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 绑定手机号
    public function bindPhone(Request $request)
    {
        $phone = $request->get('phone');
        $code = $request->get('code');
        if (empty($phone)) {
            return $this->error('手机号不能为空');
        }
        if (empty($code)) {
            return $this->error('短信验证码不能为空');
        }
        $rules = [
            'phone' => 'regex:/^1[3456789]\d{9}$/',
        ];
        $messages = [
            'phone.regex' => '手机号格式不对',
        ];
        $this->validate($request, $rules, $messages);
        $user = Auth::guard('api')->user();
        if ($user->phone == $phone) {
            return $this->error('该手机号已经绑定');
        }
        if (!app('sms')->check($phone)) {
            return $this->error('短信验证码不正确');
        }
        $exist = User::where('phone', $phone)->where('id', '!=', $user->id)->first();
        if ($exist) {
            return $this->error('该手机号被其他账号绑定');
        }
        $user->phone = $phone;
        if ($user->save()) {
            return $this->success('保存成功');
        } else {
            return $this->error('保存失败');
        }
    }

    // 绑定邮箱
    public function bindEmail(Request $request)
    {
        $email = $request->get('email');
        $code = $request->get('code');
        if (empty($email)) {
            return $this->error('邮箱不能为空');
        }
        if (empty($code)) {
            return $this->error('验证码不能为空');
        }
        $rules = [
            'email' => 'email',
        ];
        $messages = [
            'email.email' => '邮箱格式不对',
        ];
        $this->validate($request, $rules, $messages);
        $user = Auth::guard('api')->user();
        if ($user->email == $email) {
            return $this->error('该邮箱已经绑定');
        }
        if (!app('email')->check($email)) {
            return $this->error('验证码不正确');
        }
        $exist = User::where('email', $email)->where('id', '!=', $user->id)->first();
        if ($exist) {
            return $this->error('该邮箱被其他账号绑定');
        }
        $user->email = $email;
        if ($user->save()) {
            return $this->success('保存成功');
        } else {
            return $this->error('保存失败');
        }
    }

    // 完善资料
    public function complete(Request $request)
    {
        if ($request->nickname) {
            if (preg_match("/[\ \'.,:;*?~`!@#$%^zd&+=)(<>{}]|回\]|\[|\/|\\\|\"|\|/", $request->nickname)) {
                return $this->error('昵称不能包含特殊字符');
            }
            $rules = [
                'nickname' => 'string|min:2|max:50',
            ];
            $messages = [
                'nickname.string'   => '昵称格式不对',
                'nickname.min'      => '昵称最少6个字节',
                'nickname.max'      => '昵称最多50个字节',
                //'nickname.unique'   => '昵称已经被使用',
            ];
            // 验证参数，如果验证失败，则会抛出 ValidationException 的异常
            $this->validate($request, $rules, $messages);
        }
        $user = Auth::guard('api')->user();
        $request->nickname AND $user->nickname = $request->nickname;
        $request->truename AND $user->truename = $request->truename;
        $request->qq AND $user->qq = $request->qq;
        $request->avatar AND $user->avatar = $request->avatar;
        $request->sex AND $user->sex = $request->sex;
        $request->birthday AND $user->birthday = $request->birthday;
        $request->position AND $user->position = $request->position;
        $request->desc AND $user->desc = $request->desc;
        $request->company_id AND $user->company_id = $request->company_id;
        if (!empty($request->tags) && is_array($request->tags)) {
            UserHasTags::sync($this->getUserId(), $request->tags);
        }
        // 获取推荐人用户id
        if ($request->refcode) {
            $pid = User::where('refcode', $request->refcode)->value('id');
            if (empty($pid)) {
                return $this->error("推荐码不正确");
            }
            $config = Config::getConfig();
            $share_free_num = $config['base_share_get_free_num'] ?? 0;
            if ($share_free_num) {
                User::where('id', $pid)->increment('share_free_num', $share_free_num);
            }
            try {
                UserService::setLevel($user->id, $request->refcode);
                UserService::doAgentAmount($user->id, 0, 'REGISTER');
            } catch (\Exception $e) {
                return $this->error($e->getMessage());
            }
        }
        $user->save();
        return $this->success('保存成功');
    }

    // 关联公司部门ID
    public function bindCompany(Request $request)
    {
        $user_id = (int)$request->get('user_id', 0);
        $company_id = (int)$request->get('company_id', 0);
        $department_id = (int)$request->get('department_id', 0);
        if (empty($user_id)) {
            return $this->error('用户ID不能为空');
        }
        if (empty($company_id) && empty($department_id)) {
            return $this->error('company_id和department_id不能同是为空');
        }
        $data = [];
        $company_id AND $data['company_id'] = $company_id;
        $department_id AND $data['department_id'] = $department_id;
        $res = User::where('id', $user_id)->update($data);
        if (!$res) {
            return $this->error('绑定失败');
        }
        return $this->success('绑定成功');
    }

    // 更新保存标签
    public function saveTags(Request $request)
    {
        $tags = $request->tags;
        if (!is_array($tags)) {
            return $this->error('tags参数不正确');
        }
        UserHasTags::sync($this->getUserId(), $request->tags);
        return $this->success('保存成功');
    }

    // VIP商品列
    public function vipShop(Request $request)
    {
        $data = UserVipShop::where('status', 1)
        ->orderBy('id', 'ASC')
        ->get();
        return $this->success('成功', $data);
    }

    // 搜索关键词
    public function searchList(Request $request)
    {
        $is_me = $request->get('is_me', 0);
        $keyword = trim($request->get('keyword', ''));
        $data = SearchLog::select('id', 'user_id', 'keyword', 'status', DB::raw('count(keyword) as num'))
            ->where('status', 1)
            ->where(function($query) use ($is_me, $keyword) {
                if ($is_me) {
                    $query->where('user_id', $this->getUserId());
                } else {
                    $query->where('created_at', '>', strtotime("-1 month"));
                }
                $keyword AND $query->where('keyword', 'like', '%' . $keyword . '%');
            })
            ->groupBy('keyword')
            ->orderBy('num', 'DESC')
            ->orderBy('id', 'DESC')
            ->limit(10)
            ->get();
        return $this->success('成功', $data);
    }

    // 删除搜索关键词
    public function searchDel(Request $request)
    {
        if (empty($request->ids) || !is_array($request->ids)) {
            return $this->error('请传入需要删除的关键词');
        }
        $res = SearchLog::where('user_id', $this->getUserId())->whereIn('id', $request->ids)->update(['status' => 0]);
        if ($res) {
            return $this->success('删除成功');
        } else {
            return $this->error('删除失败');
        }
    }

    // 添加搜索关键词
    public function searchAdd(Request $request)
    {
        if (empty($request->keyword)) {
            return $this->error('关键词不能为空');
        }
        $info = SearchLog::where('user_id', $this->getUserId())->where('keyword', $request->keyword)->first();
        if (empty($info)) {
            $res = SearchLog::create([
                'user_id'   => $this->getUserId(),
                'keyword'   => $request->keyword,
                'device_id' => $request->device_id ??'',
                'ip'        => request()->ip(),
                'status'    => 1
            ]);
            if ($res) {
                return $this->success('保存成功');
            } else {
                return $this->error('保存失败');
            }
        } else {
            if ($info->status == 1) {
                return $this->success('保存成功');
            } else {
                $info->status = 0;
                $res = $info->save();
                if ($res) {
                    return $this->success('保存成功');
                } else {
                    return $this->error('保存失败');
                }
            }
        }
    }

    // 记录分享
    public function share(Request $request)
    {
        if (empty($request->type)) {
            return $this->error('分享类型不能为空');
        }
        if (empty($request->vid)) {
            return $this->error('分享作品ID不能为空');
        }
        $model = new Share();
        $model->type = $request->type;
        $model->vid = $request->vid;
        $model->user_id = $this->getUserId();
        $request->share_type AND $model->share_type = $request->share_type;
        $request->status AND $model->status = $request->status;
        $res = $model->save();
        if ($res) {
            return $this->success('分享成功');
        } else {
            return $this->error('分享失败');
        }
    }

    // 记录下载
    public function download(Request $request)
    {
        if (empty($request->vid)) {
            return $this->error('下载视频vid不能为空');
        }
        $model = new Download();
        $model->vid = $request->vid;
        $model->type = $request->type ?? 0;
        $model->user_id = $this->getUserId();
        $model->status = 1;
        $res = $model->save();
        if ($res) {
            return $this->success('下载成功');
        } else {
            return $this->error('下载失败');
        }
    }

    // 下载列表
    public function downloadList(Request $request)
    {
        $type = $request->get('type', '');
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = Download::join('users', 'users.id', '=', 'download.user_id')
            ->leftJoin('video', function ($join) {
                $join->on('video.id', '=', 'download.vid')
                    ->where('download.type', 0);
            })
            ->leftJoin('movie', function ($join) {
                $join->on('movie.id', '=', 'download.vid')
                    ->where('download.type', 1);
            })
            ->where('download.status', 1)
            ->where('download.user_id', $this->getUserId())
            ->where(function ($query) use ($type) {
                $type !== '' AND $query->where('type', $type);
            })
            ->where(function ($query) use ($type) {
                $query->where('movie.id', '<>', null)->orWhere('video.id', '<>', null);
            })
            ->count();
        $data = Download::join('users', 'users.id', '=', 'download.user_id')
            ->leftJoin('video', function ($join) {
                $join->on('video.id', '=', 'download.vid')
                    ->where('download.type', 0);
            })
            ->leftJoin('movie', function ($join) {
                $join->on('movie.id', '=', 'download.vid')
                    ->where('download.type', 1);
            })
            ->where('download.status', 1)
            ->where('download.user_id', $this->getUserId())
            ->where(function ($query) use ($type) {
                $type !== '' AND $query->where('type', $type);
            })
            ->where(function ($query) use ($type) {
                $query->where('movie.id', '<>', null)->orWhere('video.id', '<>', null);
            })
            ->offset($offset)
            ->limit($limit)
            ->select(DB::raw("IFNULL(video.id, movie.id) AS vid,
                IFNULL(video.title, movie.title) AS title,
                IFNULL(video.thumb, movie.thumb) AS thumb,
                IFNULL(video.video_url, movie.url) AS video_url,
                users.username,
                users.nickname,
                users.avatar,
                users.vip_end_time,
                download.id,
                download.created_at"))
            ->orderBy('download.id', 'DESC')
            ->get()->toArray();
        foreach ($data as &$value) {
            $value['vid'] = $value['vid'];
            $value['title'] = dealUrl($value['title']);
            $value['thumb'] = dealUrl($value['thumb']);
            $value['video_url'] = dealUrl($value['video_url']);
            $value['avatar'] = dealAvatar($value['avatar']);
            $value['is_vip'] = isVip($value['vip_end_time']);
            $value['vip_end_time'] = dealVipEndTime($value['vip_end_time']);
            $value['mtime'] = formatDate($value['created_at']);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 标签列表
    public function tagsList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserTags::where('status', 2)
            ->where(function($query) use ($request){
                $request->type AND $query->where('type', $request->type);
                $request->keyword AND $query->where('name', 'like', '%' . $request->keyword . '%');
            })->count();
        $data = UserTags::where('status', 2)
            ->where(function($query) use ($request){
                $request->type AND $query->where('type', $request->type);
                $request->keyword AND $query->where('name', 'like','%' . $request->keyword . '%');
            })->offset($offset)
            ->limit($limit)
            ->orderBy('sort', 'ASC')
            ->orderBy('id', 'DESC')
            ->get()->toArray();
        foreach ($data as &$value) {
            $selected = 0;
            if ($this->getUserId()) {
                $tag_ids = UserHasTags::where('user_id', $this->getUserId())->pluck('tag_id')->toArray();
                if (in_array($value['id'], $tag_ids)) {
                    $selected = 1;
                }
            }
            $value['selected'] = $selected;
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 相似用户列表
    public function sameUserList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $tag_ids = UserHasTags::where('user_id', $this->getUserId())->pluck('tag_id')->toArray();
        if (empty($tag_ids)) {
            return $this->error('没有标签');
        }
        $total = UserHasTags::from('user_has_tags AS ut')
        ->leftJoin('users AS u', 'ut.user_id', '=', 'u.id')
        ->whereIn('ut.tag_id', $tag_ids)
        ->where('u.id', '<>', $this->getUserId())
        ->count(\DB::raw('DISTINCT(ut.user_id)'));
        $data = UserHasTags::select('u.id', 'u.username', 'u.nickname', 'u.avatar', 'vip_end_time', 'position', 'desc', \DB::raw('count(*) AS same_tags'))
        ->from('user_has_tags AS ut')
        ->leftJoin('users AS u', 'ut.user_id', '=', 'u.id')
        ->whereIn('ut.tag_id', $tag_ids)
        ->where('u.id', '<>', $this->getUserId())
        ->groupBy('ut.user_id')
        ->orderBy('same_tags', 'DESC')
        ->offset($offset)
        ->limit($limit)
        ->get()
        ->toArray();
        // 是否关注
        $user_ids = array_unique(array_column($data, 'id'));
        $follows = Follow::where('user_id',$this->getUserId())->whereIn('follow_id', $user_ids)->where('status', 1)->pluck('follow_id')->toArray();
        foreach ($data as &$value) {
            $value['avatar'] = dealAvatar($value['avatar']);
            $value['is_vip'] = isVip($value['vip_end_time']);
            $value['vip_end_time'] = dealVipEndTime($value['vip_end_time']);
            $is_follow = 0;
            if (in_array($value['id'], $follows)) {
                $is_follow = 1;
            }
            $value['is_follow'] =  $is_follow;
            // 作品数
            $video_num = Video::getNum($value['id']);
            $article_num = Article::getNum($value['id']);
            $product_num = $video_num + $article_num;
            $value['product_num'] = dealNum($product_num);
            // 粉丝数
            $value['follow_num'] = dealNum(Follow::getFollowNum($value['id']));
            // 关注数
            $value['my_follow_num'] = dealNum(Follow::getMyFollowNum($value['id']));
            // 获赞数
            $value['like_num'] = dealNum(Like::getNum($value['id']));
            // 标签数
            $value['tags_num'] = UserHasTags::where('user_id', $value['id'])->count();
            //标签
            $tags = [];
            if ($this->getUserId()) {
                $tags = UserHasTags::where('user_id', $value['id'])->get();
                foreach ($tags as &$tag) {
                    $tag['tag_name'] = UserTags::where('id', $tag['tag_id'])->value('name');
                    $is_same = 0;
                    if (in_array($tag['tag_id'], $tag_ids)) {
                        $is_same = 1;
                    }
                    $tag['is_same'] = $is_same;
                }
            }
            $value['tags'] = $tags;
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    /**
     * 获取代理数量
     */
    public function agentNum(Request $request)
    {
        $level = (int)$request->get('level', 3);
        if (!in_array($level, [1, 2, 3, 4, 5])) {
            return $this->error('level不正确');
        }
        $list = [];
        $one = UserService::getNum([$this->getUserId()]);
        $list[] = [
            'level' => 1,
            'title' => UserService::$AGENT_LIST[1],
            'num'   => $one
        ];
        if ($level >= 2) {
            $twoUserIds = UserService::getChildUserIds([$this->getUserId()]);
            if ($twoUserIds) {
                $two = UserService::getNum($twoUserIds);
                $list[] = [
                    'level' => 2,
                    'title' => UserService::$AGENT_LIST[2],
                    'num' => $two
                ];
            }
        }
        if ($level >= 3) {
            $threeUserIds = UserService::getChildUserIds($twoUserIds);
            if ($threeUserIds) {
                $three = UserService::getNum($threeUserIds);
                $list[] = [
                    'level' => 3,
                    'title' => UserService::$AGENT_LIST[3],
                    'num' => $three
                ];
            }
        }
        if ($level >= 4) {
            $fourUserIds = UserService::getChildUserIds($threeUserIds);
            if ($fourUserIds) {
                $four = UserService::getNum($fourUserIds);
                $list[] = [
                    'level' => 4,
                    'title' => UserService::$AGENT_LIST[4],
                    'num' => $four
                ];
            }
        }
        if ($level >= 5) {
            $fiveUserIds = UserService::getChildUserIds($fourUserIds);
            if ($fiveUserIds) {
                $five = UserService::getNum($fiveUserIds);
                $list[] = [
                    'level' => 5,
                    'title' => UserService::$AGENT_LIST[5],
                    'num' => $five
                ];
            }
        }
        return $this->success('成功', $list);
    }

    /**
     * 获取下级代理列表
     */
    public function agentList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $user_id = $request->get('user_id', $this->getUserId());
        if (empty($user_id)) {
            return $this->error('user_id不能为空或者保持登陆');
        }
        $level = $request->get('level', 1);
        $user_ids = [];
        if ($level == 1) {
            $user_ids[] = $user_id;
        } elseif ($level == 2) {
            $user_ids = UserService::getChildUserIds([$user_id]);
        } elseif ($level == 3) {
            $twoUserIds = UserService::getChildUserIds([$user_id]);
            $user_ids = UserService::getChildUserIds($twoUserIds);
        } elseif ($level == 4) {
            $twoUserIds = UserService::getChildUserIds([$user_id]);
            $threeUserIds = UserService::getChildUserIds($twoUserIds);
            $user_ids = UserService::getChildUserIds($threeUserIds);
        } elseif ($level == 5) {
            $twoUserIds = UserService::getChildUserIds([$user_id]);
            $threeUserIds = UserService::getChildUserIds($twoUserIds);
            $fourUserIds = UserService::getChildUserIds($threeUserIds);
            $user_ids = UserService::getChildUserIds($fourUserIds);
        }

        $offset = ($page - 1) * $limit;
        $total = User::where('status', 1)
            ->whereIn('pid', $user_ids)
            ->count();
        $list = User::where('status', 1)
            ->whereIn('pid', $user_ids)
            ->select('id', 'username', 'nickname', 'avatar', 'vip_end_time', 'refcode', 'created_at')
            ->offset($offset)
            ->limit($limit)
            ->get();
        foreach ($list as &$user) {
            $user->avatar = dealAvatar($user->avatar);
            $user->is_vip = isVip($user->vip_end_time);
            $user->vip_end_time = dealVipEndTime($user->vip_end_time);
            $user->mtime = formatDate($user->created_at);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $list
        ]);
    }

    /**
     * 代理信息
     */
    public function agentInfo(Request $request)
    {
        $start_time = strtotime(date('Y-m-d'));
        $end_time = strtotime(date('Y-m-d', strtotime("+1 day")));
        $config = Config::getConfig('agent');
        $account_type = $config['agent_account'] ?? 'GOLD';
        $allChildUserIds = UserService::getAllChildUserIds($this->getUserId());
        $performance = UserAccountLog::where('status', 1)
            ->where('source', 'RECHARGE')
            ->where('type', $account_type)
            ->whereIn('user_id', $allChildUserIds)
            ->sum(strtolower($account_type));
        $earnings = UserAccountLog::where('status', 1)
            ->where('user_id', $this->getUserId())
            ->where('type', $account_type)
            ->whereIn('source', ['AGENT_RECHARGE', 'REGISTER'])
            ->sum(strtolower($account_type));
        $today_performance = UserAccountLog::where('status', 1)
            ->where('source', 'RECHARGE')
            ->where('type', $account_type)
            ->whereIn('user_id', $allChildUserIds)
            ->whereBetween('created_at', [$start_time, $end_time])
            ->sum(strtolower($account_type));
        $today_earnings = UserAccountLog::where('status', 1)
            ->where('user_id', $this->getUserId())
            ->where('type', $account_type)
            ->whereIn('source', ['AGENT_RECHARGE', 'REGISTER'])
            ->whereBetween('created_at', [$start_time, $end_time])
            ->sum(strtolower($account_type));
        $user = Auth::guard('api')->user();
        return $this->success('成功', [
            'amount' => $user->amount,
            'integral' => $user->integral,
            'gold' => $user->gold,
            'performance' => $performance,
            'earnings' => $earnings,
            'today_performance' => $today_performance,
            'today_earnings' => $today_earnings
        ]);
    }

    /**
     * 代理收益明细
     */
    public function agentEarnings(Request $request)
    {
        $config = Config::getConfig('agent');
        $account_type = $config['agent_account'] ?? 'GOLD';
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $user_id = (int)$request->get('user_id', $this->getUserId());
        $offset = ($page - 1) * $limit;
        $total = UserAccountLog::where('status', 1)
            ->where('user_id', $user_id)
            ->where('type', $account_type)
            ->whereIn('source', ['AGENT_RECHARGE', 'REGISTER'])
            ->count();
        $data = UserAccountLog::where('status', 1)
            ->where('user_id', $user_id)
            ->where('type', $account_type)
            ->whereIn('source', ['AGENT_RECHARGE', 'REGISTER'])
            ->offset($offset)
            ->limit($limit)
            ->orderBy('id', 'DESC')
            ->get();
        foreach ($data as &$value) {
            $value['source_str'] = UserAccountLog::$source_arr[$value['source']] ?? '';
        }
        return $this->success('成功', [
            'total' => $total,
            'total_page' => ceil($total / $limit),
            'current_page' => $page,
            'list' => $data
        ]);
    }

    /**
     * 打赏
     * @param Request $request
     */
    public function give(Request $request)
    {
        $amount = $request->get('amount');
        $to_user_id = $request->get('to_user_id');
        $type = $request->get('type', 'GOLD');
        $data_type = $request->get('data_type', 'ARTICLE');
        $data_id = $request->get('data_id', 0);
        if (empty($amount)) {
            return $this->error('打赏金额不能为空');
        }
        if (empty($to_user_id)) {
            return $this->error('打赏对象user_id不能为空');
        }
        if ($to_user_id == $this->getUserId()) {
            return $this->error('自己不能给自己打赏');
        }
        DB::beginTransaction();
        try {
            if (empty($data_id)) {
                $data_type = '';
            }
            $res = Give::add($data_type, $data_id, $this->getUserId(), $to_user_id, $amount);
            if (!$res) {
                DB::rollBack();
                return $this->error('打赏失败');
            }
            UserService::doAccount($this->getUserId(), -$amount, '打赏扣款', $type, 'GIVE');
            UserService::doAccount($to_user_id, $amount, '打赏付款', $type, 'GIVE');
            DB::commit();
            return $this->success('打赏成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    /**
     * 扣费
     * @param Request $request
     */
    public function rebate(Request $request)
    {
        $check = (int)$request->get('check');

        $config = Config::getConfig();

        $base_video_price = $config['base_video_price'] ??0;
        $base_video_rebate = $config['base_video_rebate'] ??0;

        if ($base_video_price != '1') {
            return $this->success('后台未开启扣费功能');
        }

        if (empty($this->getUserId())) {
            return $this->error('请先登录');
        }

        $type = $request->get('type', 'AMOUNT');
        $data_type = $request->get('data_type', 'VIDEO');
        $data_id = $request->get('data_id', 0);
        if (empty($data_id)) {
            return $this->error('扣费对象ID不能为空');
        }
        $video = Video::where('id', $data_id)->first();

        if (empty($video)) {
            return $this->error('扣费对象ID错误');
        }

        if ($video->user_id == $this->getUserId()) {
            return $this->success('自己的视频无需扣费');
        }

        if (floatval($video->price) <= 0) {
            return $this->success('本视频无需扣费');
        }

        $re = Rebate::where('status', 1)->where('data_type', $data_type)->where('data_id', $data_id)->where('user_id', $this->getUserId())->first();

        if ($re) {
            return $this->success('本视频已扣费，请直接观看');
        }

        if ($check) {
            return $this->error('该视频未付费');
        } else {

            $rebate = 0;
            if ($base_video_rebate) {
                $rebate = round(($video->price * $base_video_rebate) / 100, 2);
            }

            DB::beginTransaction();
            try {
                $res = Rebate::add($data_type, $data_id, $this->getUserId(), $video->price, $base_video_rebate, $rebate);
                if (!$res) {
                    DB::rollBack();
                    return $this->error('扣费失败');
                }
                UserService::doAccount($this->getUserId(), -$video->price, '扣费扣款', $type, 'REBATE');
                if ($video->user_id) {
                    UserService::doAccount($video->user_id, $video->price - $rebate, '扣费收款', $type, 'REBATE');
                }
                DB::commit();
                return $this->success('扣费成功');
            } catch (\Exception $e) {
                DB::rollBack();
                return $this->error($e->getMessage());
            }
        }
    }

    /**
     * 群组用户列表
     * @param Request $request
     */
    public function groupUserList(Request $request)
    {
        $group_id = (int)$request->get('group_id');
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        if (empty($group_id)) {
            return $this->error('群组id不能为空');
        }
        $total = UserGroupRelate::leftJoin('users', 'user_group_relate.user_id', '=', 'users.id')
            ->where('user_group_relate.group_id', $group_id)
            ->orderBy('user_group_relate.id', 'desc')
            ->count();
        $list = UserGroupRelate::leftJoin('users', 'user_group_relate.user_id', '=', 'users.id')
            ->where('user_group_relate.group_id', $group_id)
            ->orderBy('user_group_relate.id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->select('user_group_relate.*', 'users.username', 'users.nickname', 'users.avatar', 'users.vip_end_time', 'users.sex', 'users.is_auth')
            ->get()->toArray();
        // 已经登录情况
        if ($this->getUserId()) {
            // 是否关注
            $user_ids = array_unique(array_column($list, 'user_id'));
            $follows = Follow::where('user_id',$this->getUserId())->whereIn('follow_id', $user_ids)->where('status', 1)->pluck('follow_id')->toArray();
        }

        foreach ($list as &$value) {
            $is_follow = 0;
            if ($this->getUserId()) {
                if (in_array($value['user_id'], $follows)) {
                    $is_follow = 1;
                }
            }
            $value['is_follow'] =  $is_follow;
            $value['avatar'] = dealAvatar($value['avatar']);
            $value['is_vip'] = isVip($value['vip_end_time']);
            $value['vip_end_time'] = dealVipEndTime($value['vip_end_time']);
            $value['mtime'] = formatDate($value['created_at']);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $list
        ]);
    }

    // 群组添加
    public function saveGroup(Request $request)
    {
        $name = $request->get('name', '');
        $group_avatar = $request->get('group_avatar', '');
        $intro = $request->get('intro', '');
        $id = (int)$request->get('id', 0);
        if (empty($name)) {
            return $this->error('分组名称不能为空');
        }
        if ($id) {
            if (UserGroup::where('user_id', $this->getUserId())->whereNotIn('id', [$id])->where('name', $name)->first()) {
                return $this->error('分组已经存在');
            }
            $res = UserGroup::where('id', $id)->where('user_id', $this->getUserId())->update([
                'name' => $name,
                'group_avatar' => $group_avatar,
                'intro' => $intro,
                'status' => 1,
                'user_id' => $this->getUserId()
            ]);
            if (!$res) {
                return $this->error('更新失败');
            }
        } else {
            if (UserGroup::where('user_id', $this->getUserId())->where('name', $name)->first()) {
                return $this->error('分组已经存在');
            }
            $res = UserGroup::create([
                'name' => $name,
                'group_avatar' => $group_avatar,
                'intro' => $intro,
                'status' => 1,
                'user_id' => $this->getUserId()
            ]);
            if (!$res) {
                return $this->error('添加失败');
            }
        }
        return $this->success('保存成功');
    }

    // 删除群组
    public function delGroup(Request $request)
    {
        $id = (int)$request->get('id', 0);
        if (empty($id)) {
            return $this->error('参数不正确');
        }
        $res = UserGroup::where('user_id', $this->getUserId())->where('id', $id)->delete();
        if (!$res) {
            return $this->error('删除失败');
        }
        return $this->success('删除成功');
    }

    /**
     * 群组列表
     * @param Request $request
     */
    public function groupList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $user_id = (int)$request->get('user_id', 0);
        $offset = ($page - 1) * $limit;
        $total = UserGroup::where(function($query) use ($user_id) {
                $user_id AND $query->where('user_id', $user_id);
                })
            ->where('status', 1)
            ->orderBy('id', 'desc')
            ->count();
        $list = UserGroup::where(function($query) use ($user_id) {
                    $user_id AND $query->where('user_id', $user_id);
                })->where('status', 1)
            ->orderBy('id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->get()->toArray();
        foreach ($list as &$value) {
            $value['group_avatar'] = dealUrl($value['group_avatar']);
            $value['join_num'] = UserGroupRelate::joinNum($value['id']);
            $value['is_join'] = UserGroupRelate::hasJoin($value['id'], $this->getUserId());
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $list
        ]);
    }

    /**
     * 加入群组
     * @param Request $request
     */
    public function joinGroup(Request $request)
    {
        $group_id = $request->get('group_id');
        $user_id = $request->get('user_id', $this->getUserId());
        try {
            UserGroupRelate::join($group_id, $user_id);
            return $this->success('加入成功');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    /**
     * 加入群组
     * @param Request $request
     */
    public function quitGroup(Request $request)
    {
        $group_id = $request->get('group_id');
        $user_id = $request->get('user_id', $this->getUserId());
        try {
            UserGroupRelate::quit($group_id, $user_id);
            return $this->success('退出成功');
        } catch (\Exception $e) {
            return $this->error($e->getMessage());
        }
    }

    // 保存用户通讯录
    public function saveBook(Request $request)
    {
        $books = json_decode($request->books, true);
        if (!is_array($books)) {
            return $this->error('books参数不正确');
        }
        UserBook::sync($this->getUserId(), $books);
        return $this->success('保存成功');
    }

    // 保存用户通讯录
    public function decShareNum(Request $request)
    {
        $user = Auth::guard('api')->user();

        // 扣除免费次数
        $config = Config::getConfig();
        $vip_free_num = $config['base_share_vip_free_num'] ?? 0;
        $share_free_num = $config['base_share_get_free_num'] ?? 0;

        if (empty($vip_free_num) && empty($share_free_num)) {
            return $this->success('成功');
        }

        $start_time = strtotime(date('Y-m-d'));
        $end_time = strtotime(date("Y-m-d",strtotime("+1 day")));
        $count = UserFreeLog::where('user_id', $this->getUserId())->whereBetween('created_at', [$start_time, $end_time])->where('status', 1)->count();

        if ($this->isVip() && $vip_free_num && $vip_free_num > $count) {
            UserFreeLog::create([
                'type' => 1,
                'status' => 1,
                'user_id' => $this->getUserId(),
            ]);
            return $this->success('成功');
        }

        if ($share_free_num) {
            $res = User::where('id', $this->getUserId())->where('share_free_num', '>', '0')->decrement('share_free_num');
            if ($res) {
                UserFreeLog::create([
                    'type' => 1,
                    'status' => 1,
                    'user_id' => $this->getUserId(),
                ]);
                return $this->success('成功');
            }
        }

        return $this->error('免费次数已经用完，请开通会员或者推广获取更多免费观看次数');
    }

    /**
     * 签到列表
     * @param Request $request
     * @return void
     */
    public function signList(Request $request)
    {
        if (empty($this->getUserId())) {
            return $this->error('请先登录');
        }
        $start_date = $request->get('start_date');
        $end_date = $request->get('end_date');

        if (empty($start_date) || empty($end_date)) {
            return $this->error('参数必填');
        }

        if ($start_date >= $end_date) {
            return $this->error('结束时间必须大于开始时间');
        }

        if ($end_date > date('Y-m-d')) {
            return $this->error('结束日期不能大于当前日期');
        }

        $list = SignInLog::where('status', 1)->where('day', '>', $start_date)->where('day', '<=', $end_date)->where('user_id', $this->getUserId())->orderBy('day', 'ASC')->get();

        return $this->success('成功', [
            'list' => $list
        ]);
    }

    /**
     * 签到记录
     * @param Request $request
     * @return void
     */
    public function signView(Request $request)
    {
        if (empty($this->getUserId())) {
            return $this->error('请先登录');
        }
        $day = $request->get('day', date('Y-m-d'));
        $data = SignInLog::where('status', 1)->where('day', $day)->where('user_id', $this->getUserId())->first();

        return $this->success('成功', $data);
    }

    /**
     * 签到
     * @param Request $request
     */
    public function signin(Request $request)
    {
        if (empty($this->getUserId())) {
            return $this->error('请先登录');
        }

        $config = Config::getConfig();

        $base_sign_in_get = $config['base_sign_in_get'] ??0;

        if (empty($base_sign_in_get)) {
            return $this->error('未配置签到获取数量');
        }

        $day = $request->get('day', date('Y-m-d'));
        $type = $request->get('type', 'AMOUNT');

        if (date('Y-m-d', strtotime($day)) != $day) {
            return $this->error('日期不存在或者格式错误');
        }

        $date7 = date('Y-m-d', strtotime('-7 days'));

        if ($day < $date7) {
            return $this->error('不能补签7日前的日期');
        }

        if ($day > date('Y-m-d')) {
            return $this->error('日期不能大于当前日期');
        }

        $res = SignInLog::where('status', 1)->where('day', $day)->where('user_id', $this->getUserId())->first();

        if ($res) {
            return $this->success('请勿重复签到');
        }

        DB::beginTransaction();
        try {
            $res = SignInLog::add($this->getUserId(), $day);
            if (!$res) {
                DB::rollBack();
                return $this->error('签到失败');
            }
            UserService::doAccount($this->getUserId(), $base_sign_in_get, '签到所得', $type, 'SIGNIN');
            DB::commit();
            return $this->success('签到成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    /**
     * 代言
     * @param Request $request
     */
    public function speakRelate(Request $request)
    {
        $goods_id = $request->get('goods_id', 0);
        $s_price = $request->get('s_price', 0);
        $s_day = $request->get('s_day', 0);
        $start_date = $request->get('start_date', date('Y-m-d'));
        $info = SpeakRelate::where('status', 1)->where('user_id', $this->getUserId())->where('goods_id', $goods_id)->first();
        if ($info) {
            return $this->error('已经代言');
        }
        DB::beginTransaction();
        try {
            $res = SpeakRelate::add($this->getUserId(), $goods_id, $s_price, $s_day, $start_date);
            if (!$res) {
                DB::rollBack();
                return $this->error('代言失败');
            }
            DB::commit();
            return $this->success('代言成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    /**
     * 代言人列表
     * @param Request $request
     */
    public function speakList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = SpeakRelate::leftJoin('users', function ($join){
                    $join->on('speak_relate.user_id', '=', 'users.id');
                })
                ->where(function($query) use ($request){
                    $request->username AND $query->where('users.username', $request->username);
                    $request->nickname AND $query->where('users.nickname', $request->nickname);
                    $request->truename AND $query->where('users.truename', $request->truename);
                })
                ->where('speak_relate.status', 1)
                ->count();
        $data = SpeakRelate::leftJoin('users', function ($join){
                $join->on('speak_relate.user_id', '=', 'users.id');
            })
            ->where(function($query) use ($request){
                $request->username AND $query->where('users.username', $request->username);
                $request->nickname AND $query->where('users.nickname', $request->nickname);
                $request->truename AND $query->where('users.truename', $request->truename);
            })
            ->where('speak_relate.status', 1)
            ->select('speak_relate.*', 'users.username', 'users.nickname', 'users.truename', 'users.sex', 'users.avatar', 'users.vip_end_time')
            ->orderBy('speak_relate.id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->get()
            ->toArray();
        foreach ($data as &$value) {
            $value['avatar'] = dealAvatar($value['avatar']);
            $value['follow_num'] = dealNum(Follow::getFollowNum($value['user_id']));
            $value['like_num'] = dealNum(Like::getNum($value['user_id']));
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 分组标签列表
    public function groupTagsList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserGroupTags::where('status', 1)
            ->where('user_id', $this->getUserId())
            ->count();
        $data = UserGroupTags::where('status', 1)
            ->where('user_id', $this->getUserId())
            ->offset($offset)
            ->limit($limit)
            ->orderBy('sort', 'ASC')
            ->orderBy('id', 'DESC')
            ->get()->toArray();
        foreach ($data as &$value) {
            $value['joinNum'] = UserGroupTagsRelate::joinNum($value['id']);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 分组标签保存
    public function saveGroupTags(Request $request)
    {
        $name = $request->get('name', '');
        $sort = (int)$request->get('sort', 0);
        $id = (int)$request->get('id', 0);
        if ($id) {
            if (UserGroupTags::where('user_id', $this->getUserId())->whereNotIn('id', [$id])->where('name', $name)->first()) {
                return $this->error('标签已经存在');
            }
            $res = UserGroupTags::where('id', $id)->where('user_id', $this->getUserId())->update([
                'name' => $name,
                'sort' => $sort,
                'status' => 1,
                'user_id' => $this->getUserId()
            ]);
            if (!$res) {
                return $this->error('更新失败');
            }
        } else {
            if (UserGroupTags::where('user_id', $this->getUserId())->where('name', $name)->first()) {
                return $this->error('标签已经存在');
            }
            $res = UserGroupTags::create([
                'name' => $name,
                'sort' => $sort,
                'status' => 1,
                'user_id' => $this->getUserId()
            ]);
            if (!$res) {
                return $this->error('添加失败');
            }
        }
        return $this->success('保存成功');
    }

    // 分组标签删除
    public function delGroupTags(Request $request)
    {
        $id = (int)$request->get('id', 0);
        if (empty($id)) {
            return $this->error('标签ID不能为空');
        }
        $res = UserGroupTags::where('user_id', $this->getUserId())->where('id', $id)->delete();
        if (!$res) {
            return $this->error('删除失败');
        }
        return $this->success('删除成功');
    }

        // 分组标签排序
    public function groupTagsSort(Request $request)
    {
        $tags = $request->tags;
        if (!is_array($tags)) {
            return $this->error('tags参数不正确');
        }
        foreach ($tags as $key => $tag_id) {
            UserGroupTags::where('user_id', $this->getUserId())->where('id', $tag_id)->update([
                'sort' => ($key + 1)
            ]);
        }
        return $this->success('保存成功');
    }

    /**
     * 分组标签用户列表
     * @param Request $request
     */
    public function groupTagsRelateList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $tag_id = (int)$request->get('tag_id', 0);
        if (empty($tag_id)) {
            return $this->error('参数不正确');
        }
        $offset = ($page - 1) * $limit;
        $total = UserGroupTagsRelate::leftJoin('users', function ($join){
                $join->on('user_group_tags_relate.user_id', '=', 'users.id');
            })
            ->where('tag_id', $tag_id)
            ->count();
        $data = UserGroupTagsRelate::leftJoin('users', function ($join){
                $join->on('user_group_tags_relate.user_id', '=', 'users.id');
            })
            ->where('tag_id', $tag_id)
            ->select('user_group_tags_relate.*', 'users.username', 'users.nickname', 'users.truename', 'users.avatar')
            ->orderBy('user_group_tags_relate.id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->get()
            ->toArray();
        foreach ($data as &$value) {
            $value['avatar'] = dealAvatar($value['avatar']);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 分组标签加入
    public function addGroupTagsRelate(Request $request)
    {
        $user_id = (int)$request->get('user_id', 0);
        $tag_id = (int)$request->get('tag_id', 0);
        if (empty($user_id) || empty($tag_id)) {
            return $this->error('参数不正确');
        }
        try {
            UserGroupTagsRelate::join($tag_id, $user_id);
            DB::commit();
            return $this->success('成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    // 分组标签退出
    public function delGroupTagsRelate(Request $request)
    {
        $user_id = (int)$request->get('user_id', 0);
        $tag_id = (int)$request->get('tag_id', 0);
        if (empty($user_id) || empty($tag_id)) {
            return $this->error('参数不正确');
        }
        try {
            UserGroupTagsRelate::quit($tag_id, $user_id);
            DB::commit();
            return $this->success('成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    /**
     * 好友列表
     * @param Request $request
     */
    public function relateList(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserRelate::leftJoin('users', function ($join){
            $join->on('user_relate.to_user_id', '=', 'users.id');
        })
            ->where('user_id', $this->getUserId())
            ->count();
        $data = UserRelate::leftJoin('users', function ($join){
            $join->on('user_relate.to_user_id', '=', 'users.id');
        })
            ->where('user_id', $this->getUserId())
            ->select('user_relate.*', 'users.username', 'users.nickname', 'users.truename', 'users.avatar')
            ->orderBy('user_relate.id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->get()
            ->toArray();
        foreach ($data as &$value) {
            $value['avatar'] = dealAvatar($value['avatar']);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 添加好友
    public function relate(Request $request)
    {
        $user_id = (int)$request->get('user_id', 0);
        $to_user_id = (int)$request->get('to_user_id', 0);
        if (empty($user_id) || empty($to_user_id)) {
            return $this->error('参数不正确');
        }
        if ($user_id == $to_user_id) {
            return $this->error('不能加自己为好友');
        }
        try {
            UserRelate::join($user_id, $to_user_id);
            DB::commit();
            return $this->success('成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    // 删除好友
    public function delRelate(Request $request)
    {
        $user_id = (int)$request->get('user_id', 0);
        $to_user_id = (int)$request->get('to_user_id', 0);
        if (empty($user_id) || empty($to_user_id)) {
            return $this->error('参数不正确');
        }
        if ($user_id == $to_user_id) {
            return $this->error('参数不能相同');
        }
        try {
            UserRelate::quit($user_id, $to_user_id);
            DB::commit();
            return $this->success('成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    /**
     * 黑名单列表
     * @param Request $request
     */
    public function blacklist(Request $request)
    {
        $page = (int)$request->get('page', 1);
        $limit = (int)$request->get('limit', 10);
        $offset = ($page - 1) * $limit;
        $total = UserBlacklist::leftJoin('users', function ($join){
            $join->on('user_blacklist.to_user_id', '=', 'users.id');
        })
            ->where('user_id', $this->getUserId())
            ->count();
        $data = UserBlacklist::leftJoin('users', function ($join){
            $join->on('user_blacklist.to_user_id', '=', 'users.id');
        })
            ->where('user_id', $this->getUserId())
            ->select('user_blacklist.*', 'users.username', 'users.nickname', 'users.truename', 'users.avatar')
            ->orderBy('user_blacklist.id', 'DESC')
            ->offset($offset)
            ->limit($limit)
            ->get()
            ->toArray();
        foreach ($data as &$value) {
            $value['avatar'] = dealAvatar($value['avatar']);
        }
        return $this->success('成功', [
            'total'         => $total,
            'total_page'    => ceil($total / $limit),
            'current_page'  => $page,
            'list'          => $data
        ]);
    }

    // 添加好友
    public function addBlacklist(Request $request)
    {
        $user_id = (int)$request->get('user_id', 0);
        $to_user_id = (int)$request->get('to_user_id', 0);
        if (empty($user_id) || empty($to_user_id)) {
            return $this->error('参数不正确');
        }
        if ($user_id == $to_user_id) {
            return $this->error('不能把自己加入黑名单');
        }
        try {
            UserBlacklist::join($user_id, $to_user_id);
            DB::commit();
            return $this->success('成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }

    // 删除黑名单
    public function delBlacklist(Request $request)
    {
        $user_id = (int)$request->get('user_id', 0);
        $to_user_id = (int)$request->get('to_user_id', 0);
        if (empty($user_id) || empty($to_user_id)) {
            return $this->error('参数不正确');
        }
        if ($user_id == $to_user_id) {
            return $this->error('参数不能相同');
        }
        try {
            UserBlacklist::quit($user_id, $to_user_id);
            DB::commit();
            return $this->success('成功');
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error($e->getMessage());
        }
    }
}
